package service;

import exception.NotEnoughMoneyException;
import repository.WalletEntity;
import repository.WalletRepository;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class WalletBo {
    private int id;
    private double balance;
    private List<String> flows;
    private double freezeBalance;
    private boolean canOverdraft;
    private double overdraftLimit;

    private WalletRepository walletRepository;

    public WalletBo(int id, double balance, List<String>flows, double freezeBalance, boolean canOverdraft, double overdraftLimit, WalletRepository walletRepository){
        this.id = id;
        this.balance = balance;
        this.flows = flows;
        this.freezeBalance = freezeBalance;
        this.canOverdraft = canOverdraft;
        this.overdraftLimit = overdraftLimit;
        this.walletRepository = walletRepository;
    }

    /**
     *  充值功能
     */
    public void recharge(int walletId, double money) {
        double newBalance = money + walletRepository.getBalance(walletId);
        walletRepository.updateBalance(walletId, newBalance);
        updateFlows(TransactionType.RECHARGE, walletId, money);
    };

    /**
     *  提现功能
     */
    public void withdraw(int walletId, double money) throws NotEnoughMoneyException {
        try {
            if(walletRepository.getBalance(walletId)< money){
                throw new NotEnoughMoneyException("余额不足！");
            } else {
                double newBalance = walletRepository.getBalance(walletId) - money;
                walletRepository.updateBalance(walletId, newBalance);
                updateFlows(TransactionType.WITHDRAW, walletId, money);
            }
        }catch (NotEnoughMoneyException e){
            System.out.println("提现失败！");
        }

    };

    /**
     *  支付功能
     */
    public void pay(int outWalletId, int inWalletId, double money) throws NotEnoughMoneyException {
        try {
            if(walletRepository.getCanOverdraft(outWalletId)){
                if(walletRepository.getBalance(outWalletId)+ walletRepository.getOverdraftLimit(outWalletId)< money){
                    throw new NotEnoughMoneyException("余额不足！");
                } else {
                    double newOutBalance = walletRepository.getBalance(outWalletId) - money;
                    double newInBalance = walletRepository.getBalance(inWalletId) + money;
                    walletRepository.updateBalance(outWalletId, newOutBalance);
                    walletRepository.updateBalance(inWalletId, newInBalance);
                    updateFlows(TransactionType.PAY_OUT, outWalletId, money);
                    updateFlows(TransactionType.PAY_IN, inWalletId, money);
                }
            } else {
                if(walletRepository.getBalance(outWalletId)< money){
                    throw new NotEnoughMoneyException("余额不足！");
                } else {
                    double newOutBalance = walletRepository.getBalance(outWalletId) - money;
                    double newInBalance = walletRepository.getBalance(inWalletId) + money;
                    walletRepository.updateBalance(outWalletId, newOutBalance);
                    walletRepository.updateBalance(inWalletId, newInBalance);
                    updateFlows(TransactionType.PAY_OUT, outWalletId, money);
                    updateFlows(TransactionType.PAY_IN, inWalletId, money);
                }
            }
        }catch (NotEnoughMoneyException e ){
            System.out.println("支付失败！");
        }
    };

    /**
     *  查询余额
     */
    public double getBalance(int walletId){
        return walletRepository.getBalance(walletId);
    };

    /**
     *  查询交易流水
     */
    public List<String> getFlows(int walletId){
        return walletRepository.getFlows(walletId);
    };

    /**
     *  冻结：冻结部分余额
     */
    public void freezeBalance(int walletId, double money) throws NotEnoughMoneyException {
        try {
            if(walletRepository.getBalance(walletId)< money){
                throw new NotEnoughMoneyException("余额不足！");
            } else {
                double newBalance = walletRepository.getBalance(walletId) - money;
                walletRepository.freezeBalance(walletId, newBalance, money);
                updateFlows(TransactionType.FREEZE, walletId, money);
            }
        }catch (NotEnoughMoneyException e){
            System.out.println("冻结失败！");
        }

    };

    /**
     *  透支：能否透支、透支额度
     */
    public void authorizedOverdraft(int walletId, double limit){
        walletRepository.canOverdraft(walletId,limit);
    };
    public void unAuthorizedOverdraft(int walletId){
        walletRepository.canNotOverdraft(walletId);
    };

    /**
     * 更新交易流水
     */
    public void updateFlows(TransactionType transactionType, int walletId, double money){
        String flow = "";
        String transactionText = "交易类型：";
        SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss");
        Date date = new Date(System.currentTimeMillis());
        String time = " 交易时间：" + formatter.format(date);
        String moneyText = " 交易金额：" + String.valueOf(money);
        String[] transactionTypes = { "充值", "提现", "支出", "收入","冻结" };
        switch (transactionType){
            case RECHARGE:
                flow = transactionText+transactionTypes[0]+time+moneyText;
                walletRepository.addFlows(walletId, flow);
                break;

            case WITHDRAW:
                flow = transactionText+transactionTypes[1]+time+moneyText;
                walletRepository.addFlows(walletId, flow);
                break;

            case PAY_OUT:
                flow = transactionText+transactionTypes[2]+time+moneyText;
                walletRepository.addFlows(walletId, flow);
                break;

            case PAY_IN:
                flow = transactionText+transactionTypes[3]+time+moneyText;
                walletRepository.addFlows(walletId, flow);
                break;

            case FREEZE:
                flow = transactionText+transactionTypes[4]+time+moneyText;
                walletRepository.addFlows(walletId, flow);
                break;

            default:
                throw new IllegalStateException("Unexpected value: " + transactionType);
        }
    }

}
